package controllers.api;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Type;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import play.data.Upload;
import play.libs.MimeTypes;
import play.mvc.Router;
import play.mvc.Http.StatusCode;
import siena.core.Base64;
import utils.files.GAEFileService;
import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.datastore.Link;
import com.google.appengine.api.files.AppEngineFile;
import com.google.appengine.api.files.FileService;
import com.google.appengine.api.files.FileServiceFactory;
import com.google.appengine.api.files.FileWriteChannel;
import com.google.appengine.api.files.LockException;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import models.ContentTag;
import models.Photo;
import models.Tag;
import models.Photo.Image;
import models.User;
import controllers.BaseController;
import controllers.Check;
import controllers.Data;
import controllers.SecuredBaseController;
import controllers.Security;
import models.Content;

public class Photos extends MeApi {
	
	public static void list(Integer offset, Integer limit, Boolean owned) {
		if(owned==null) owned=true;
		if(offset == null) offset = 0;
		if(limit==null || limit > LIMIT || limit==0) {
			limit = LIMIT;
		}
		User current = getCurrentUser();
		Data<Photo> data = new Data<Photo>();
		if(owned) {
			data.total = Photo.countByOwner(current);
			data.data = Photo.paginate(Photo.all(current), offset, limit);
		} else {
			data.total = ContentTag.countByTag(Tag.findOrCreateByName("shared", current));
			data.data = ContentTag.paginateByTag(Content.ContentType.PHOTO, 
					ContentTag.allByTag(Tag.findOrCreateByName("shared", current)), offset, limit);
		}	
		Type dataType = new TypeToken<Data<Photo>>(){}.getType();
		renderJSON(gson().toJson(data, dataType));
	}
	
	public static void add(Upload data) throws IOException {
		//TO-DO Security control check.
		String key = GAEFileService.createFile(MimeTypes.getContentType(data.getFileName()), data.getFileName(),data.asBytes());
		User currentUser = getCurrentUser();
		Photo photo = new Photo();
		photo.filename = data.getFileName();
		photo.owner = currentUser;
		response.status = StatusCode.CREATED;
		Map map = new HashMap();
		map.put("key", key);
		String url = Router.reverse("api.Files.serve", map).url;
		Image original = photo.new Image();
		original.key = key;
		original.source = url;
		original.height = 100;
		original.width = 50;
		photo.original = original;
		photo.insert();
		map = new HashMap();
		map.put("id", photo.id);
		url = Router.reverse("api.Photos.get", map).url;
		response.setHeader("location", url);
		renderJSON(gson().toJson(photo));
    }
	
	public static void get(Long id) {
		Photo photo = Photo.findById(id);
		if(photo == null) {
			notFound();
		}
		User currentUser = getCurrentUser();
		if(photo.owner.id!=currentUser.id && 
				!ContentTag.exists(photo.id, Tag.findOrCreateByName("shared", currentUser)))
			forbidden();
		renderJSON(gson().toJson(photo));
	}
	
	public static void delete(Long id) {
		User currentUser = getCurrentUser();
		Photo photo = Photo.findById(id);
		if(photo == null) notFound();
		if(photo.owner.id!=currentUser.id) forbidden();
		photo.delete();
		response.status = StatusCode.NO_RESPONSE;
	}
	
	public static void takephoto(String image) {
    	String[] imageData = image.split(",");
    	try {
			byte[] imageBytes = Base64.decode(imageData[imageData.length-1]);
			String key = GAEFileService.createFile(MimeTypes.getContentType("me-"+System.currentTimeMillis()), "me-"+System.currentTimeMillis(),imageBytes);
			User currentUser = getCurrentUser();
			Photo photo = new Photo();
			photo.filename = "me-"+System.currentTimeMillis();
			photo.owner = currentUser;
			response.status = StatusCode.CREATED;
			Map map = new HashMap();
			map.put("key", key);
			String url = Router.reverse("api.Files.serve", map).url;
			Image original = photo.new Image();
			original.key = key;
			original.source = url;
			original.height = 100;
			original.width = 50;
			photo.original = original;
			photo.insert();
			map = new HashMap();
			map.put("id", photo.id);
			url = Router.reverse("api.Photos.get", map).url;
			response.setHeader("location", url);
			renderJSON(gson().toJson(photo));
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			error();
		}
    }
}